using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json;
using UnityEngine;
using Voodoo.Sauce.Internal.Extension;

namespace Voodoo.Sauce.Internal.Analytics
{
	internal class AnalyticsEventLogger
	{
		private const string TAG = "AnalyticsEventLogger";

		private const string VOODOO_ANALYTICS_WRAPPER_NAME = "VoodooAnalytics";

		private const string PLAYER_PREF_RECORDING_AT_STARTUP_KEY = "van_debugger_recording_startup";

		private static AnalyticsEventLogger _instance;

		private readonly List<DebugAnalyticsLog> _logsList = new List<DebugAnalyticsLog>(500);

		private readonly HashSet<string> _logsIdList = new HashSet<string>();

		private bool _isAnalyticsDebuggingEnabled;

		internal bool IsRecordingEvents { get; private set; }

		internal bool IsRecordingAtStartup
		{
			get
			{
				if (NintendoPlayerPrefs.HasKey("van_debugger_recording_startup"))
				{
					return NintendoPlayerPrefs.GetInt("van_debugger_recording_startup") == 1;
				}
				return Application.identifier == "io.voodoo.voodoosaucetestapp";
			}
			set
			{
				if (value)
				{
					NintendoPlayerPrefs.SetInt("van_debugger_recording_startup", 1);
				}
				else
				{
					NintendoPlayerPrefs.SetInt("van_debugger_recording_startup", 0);
				}
			}
		}

		internal event Action<bool> OnRecordingStateChange;

		internal static event Action<DebugAnalyticsLog, bool> OnAnalyticsEventStateChanged;

		internal List<DebugAnalyticsLog> GetLocalAnalyticsLog(string wrapperNameFilter = null)
		{
			if (!string.IsNullOrEmpty(wrapperNameFilter))
			{
				return _logsList.Where((DebugAnalyticsLog nameInList) => nameInList.WrapperName.Contains(wrapperNameFilter)).ToList();
			}
			return _logsList;
		}

		internal static AnalyticsEventLogger GetInstance()
		{
			return _instance ?? (_instance = new AnalyticsEventLogger());
		}

		private AnalyticsEventLogger()
		{
		}

		internal void Init()
		{
			SetAnalyticsEventRecording(IsRecordingAtStartup);
		}

		private void LogEventLocallyIfRelevant(string wrapperName, string eventName, DebugAnalyticsStateEnum state, string eventId, Dictionary<string, object> param = null, string error = "")
		{
			bool flag = state != DebugAnalyticsStateEnum.ForwardedTo3rdParty && _logsIdList.Contains(eventId);
			if (!_isAnalyticsDebuggingEnabled && !IsRecordingEvents && !flag)
			{
				return;
			}
			DebugAnalyticsLog localAnalyticsLog = new DebugAnalyticsLog(wrapperName, eventName, param, state, eventId, error, AnalyticsSessionManager.Instance().SessionInfo.id, GetAdditionalInformationFromJson(param));
			bool arg = false;
			if (IsRecordingEvents || flag)
			{
				if (!flag)
				{
					_logsList.Add(localAnalyticsLog);
					_logsIdList.Add(localAnalyticsLog.EventId);
				}
				else
				{
					int index = _logsList.FindIndex((DebugAnalyticsLog logItem) => logItem.EventId.Contains(localAnalyticsLog.EventId));
					_logsList[index] = localAnalyticsLog;
					arg = true;
				}
			}
			AnalyticsEventLogger.OnAnalyticsEventStateChanged?.Invoke(localAnalyticsLog, arg);
		}

		internal void LogEventSentTo3RdParty(string wrapperName, string eventName, string eventId, [CanBeNull] Dictionary<string, object> param = null)
		{
			LogEventLocallyIfRelevant(wrapperName, eventName, DebugAnalyticsStateEnum.ForwardedTo3rdParty, eventId, param);
		}

		internal void LogEventException(string wrapperName, string eventName, string eventId, [CanBeNull] Dictionary<string, object> param, Exception e)
		{
			LogEventLocallyIfRelevant(wrapperName, eventName, DebugAnalyticsStateEnum.Error, eventId, param, e.ToString());
		}

		internal void LogEventsSentSuccessfully(List<string> eventJsons)
		{
			LogAnalyticsSentOrErrorEvent("VoodooAnalytics", eventJsons, DebugAnalyticsStateEnum.Sent);
		}

		internal void LogEventsSentError(List<string> eventJsons, string error)
		{
			LogAnalyticsSentOrErrorEvent("VoodooAnalytics", eventJsons, DebugAnalyticsStateEnum.SentButErrorFromServer, error);
		}

		private void LogAnalyticsSentOrErrorEvent(string wrapperName, List<string> eventJsons, DebugAnalyticsStateEnum stateEnum, string error = "")
		{
			foreach (string eventJson in eventJsons)
			{
				if (string.IsNullOrEmpty(eventJson))
				{
					continue;
				}
				Dictionary<string, object> dictionary;
				try
				{
					dictionary = JsonUtils.DeserializeAsDictionary(eventJson);
				}
				catch (Exception ex)
				{
					VoodooLog.LogError(Module.ANALYTICS, "AnalyticsEventLogger", ex.Message);
					if (!(ex is OverflowException) && !(ex is InvalidCastException) && !(ex is ArgumentOutOfRangeException))
					{
						_ = ex is ArrayTypeMismatchException;
					}
					continue;
				}
				if (dictionary != null)
				{
					string eventName = TryToGetStringOrEmpty("name", dictionary);
					string eventId = TryToGetStringOrEmpty("id", dictionary);
					LogEventLocallyIfRelevant(wrapperName, eventName, stateEnum, eventId, dictionary, error);
				}
			}
		}

		private static string TryToGetStringOrEmpty<T>(T key, Dictionary<T, object> data)
		{
			if (!data.ContainsKey(key))
			{
				return "";
			}
			object obj = data[key];
			if (obj == null)
			{
				return "";
			}
			return obj.ToString();
		}

		private static string GetAdditionalInformationFromJson(Dictionary<string, object> dict, string additionalInformation = "")
		{
			if (dict == null)
			{
				return additionalInformation;
			}
			Dictionary<string, object> dictionary = null;
			if (dict.TryGetValue("data", out var value))
			{
				if (value is string)
				{
					dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(value.ToString());
				}
				else if (value is Dictionary<string, object> dictionary2)
				{
					dictionary = dictionary2;
				}
			}
			if (dict.TryGetValue("session_length", out var value2))
			{
				TimeSpan timeSpan = TimeSpan.FromSeconds(Convert.ToDouble(value2));
				if (timeSpan.Minutes > 0 || timeSpan.Seconds > 0)
				{
					additionalInformation = "session_length: ";
					if (timeSpan.Minutes > 0)
					{
						additionalInformation += (timeSpan.Minutes + "min").BoldText();
						if (timeSpan.Seconds > 0)
						{
							additionalInformation += " ";
						}
					}
					if (timeSpan.Seconds > 0)
					{
						additionalInformation += (timeSpan.Seconds + "s").BoldText();
					}
				}
			}
			if (dict.TryGetValue("game_count", out var value3))
			{
				if (additionalInformation != "")
				{
					additionalInformation += ", ";
				}
				additionalInformation = additionalInformation + "game_count: " + value3.ToString().BoldText();
			}
			if (dictionary != null)
			{
				additionalInformation = GetAdditionalInformationFromJson(dictionary, additionalInformation);
			}
			return additionalInformation;
		}

		internal void SetAnalyticsDebugging(bool enabled)
		{
			_isAnalyticsDebuggingEnabled = enabled;
		}

		internal void SetAnalyticsEventRecording(bool enabled)
		{
			if (enabled != IsRecordingEvents)
			{
				IsRecordingEvents = enabled;
				this.OnRecordingStateChange?.Invoke(IsRecordingEvents);
			}
		}

		internal void FlushAnalyticsLogs()
		{
			_logsIdList.Clear();
			_logsList.Clear();
		}
	}
}
